package rpc.remote.handler;

import lombok.extern.slf4j.Slf4j;
import rpc.exceprion.RpcException;
import rpc.factory.SingletonFactory;
import rpc.provider.ServiceProvider;
import rpc.provider.impl.ZkServiceProviderImpl;
import rpc.remote.dto.RpcRequest;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @ClassName: RpcRequestHandler
 * @Description: 专门处理RpcRequest
 * @author: Kowk
 * @since:1.0.0
 */
@Slf4j
public class RpcRequestHandler implements Serializable {
    private final ServiceProvider serviceProvider;

    public RpcRequestHandler() {
        this.serviceProvider = SingletonFactory.getInstance(ZkServiceProviderImpl.class);
    }

    //处理RpcRequest，调用对应的方法并反对这个方法
    public Object handle(RpcRequest request){
        Object service = serviceProvider.getService(request.getRpcServiceName());
        return invokeTargetMethod(request, service);
    }


    /**
     * @Description: 得到方法执行的结果
     * @Param: [request：客户端的请求, service：提供服务的对象]
     * @return: java.lang.Object：方法的执行结果
     */
    private Object invokeTargetMethod(RpcRequest request, Object service) {
        Object result;
        try {
            Method method = service.getClass().getMethod(request.getMethodName(),request.getParamTypes());
            result = method.invoke(service,request.getParameters());
            log.info("服务[{}]成功调用方法[{}]",request.getInterfaceName(),request.getMethodName());
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
            throw new RpcException(e.getMessage(),e);
        }
        return result;
    }

}
